package com.prs.crm.domain.project;

import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.Lob;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;

import org.courser.Util;
import org.hibernate.annotations.Cascade;

import com.prs.crm.context.Constrains;
import com.prs.crm.domain.Attachment;
import com.prs.crm.domain.SimpleFlowEntity;
import com.prs.crm.domain.hr.Person;

@Entity
@Table(name="prj_task")
public class Task extends SimpleFlowEntity{

	
	private static final long serialVersionUID = 97057989791257320L;
	
	
	@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
	private Integer id;
	
	private String name;
	//执行人
	@ManyToOne(fetch=FetchType.LAZY)
	private Person executor;
	
	@ManyToMany(fetch=FetchType.LAZY)
	@OrderBy
	private Set<Person> joiner;//参与者
	
	@ManyToMany(fetch=FetchType.LAZY)
	@JoinTable(name = "prj_task_perusal", joinColumns = { @JoinColumn(name ="task_id" )}, inverseJoinColumns = { @JoinColumn(name = "person_id") })
	@OrderBy
	private Set<Person> perusals;
	
	/**
	 * 任务反馈的周期(单位天)
	 */
	private Integer cycles;
	
	/**
	 * 任务反馈周期类型（月  周  日 )
	 */
	private Integer cycleType;
	
	/**
	 * 点评
	 */
	@OneToMany(fetch=FetchType.LAZY,mappedBy="task")
	@OrderBy
	@Cascade({org.hibernate.annotations.CascadeType.ALL,org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
	private Set<TaskCritique> critiques;
	
	
	/**
	 * 最后提交日期
	 */
	private Date lastSubmitTime;
	
	/**
	 * 任务附件，在任务执行过程中提交
	 */
	@OneToMany(fetch=FetchType.LAZY,mappedBy="task")
	@OrderBy
	@Cascade({org.hibernate.annotations.CascadeType.ALL,org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
	private Set<TaskAttach> attachs;
	
	/**
	 * 参考资料
	 */
	@ManyToMany(fetch=FetchType.LAZY)
	@OrderBy
	@Cascade({org.hibernate.annotations.CascadeType.ALL,org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
	private Set<Attachment>  references;
	
	@ManyToMany(fetch=FetchType.LAZY)
	@OrderBy
	@JoinTable(name = "prj_task_result", joinColumns = { @JoinColumn(name ="task_id" )}, inverseJoinColumns = { @JoinColumn(name = "attach_id") })
	@Cascade({org.hibernate.annotations.CascadeType.ALL,org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
	private Set<Attachment> results;
	
	//完成的总结
	@Lob
	private String  summary;
	
	private Date startTime;
	
	private Date endTime;
	
	private Date realStartTime;
	
	private Date realEndTime;
	
	private Integer status;
	
	@OneToMany(mappedBy="parent",fetch=FetchType.LAZY)
	@Cascade({org.hibernate.annotations.CascadeType.ALL,org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
	private Set<Task> childTasks;
	
	@ManyToOne
	private Task parent;
	
	@ManyToOne
	private Project project;
	
	/**
	 * 最近该提交时间
	 */
	private Date nearSubmitTime;
	
	/**
	 * 任务等级
	 */
	private Integer grade;
	
	/**
	 * 进度
	 */
	private Integer rate;
	

	
	//描述
	@Lob
	private String remark;

	public void setId(Integer id) {
		this.id = id;
	}


	public Integer getId() {
		return id;
	}


	public void setChildTasks(Set<Task> childTasks) {
		this.childTasks = childTasks;
	}


	public Set<Task> getChildTasks() {
		return childTasks;
	}


	public void setParent(Task parent) {
		this.parent = parent;
	}


	public Task getParent() {
		return parent;
	}
	
	public void addChildTask(Task childTask)
	{
		if (childTasks==null)
			childTasks = new HashSet<Task>();
		childTasks.add(childTask);
	}


	public void setProject(Project project) {
		this.project = project;
	}


	public Project getProject() {
		return project;
	}


	public void setGrade(Integer grade) {
		this.grade = grade;
	}


	public Integer getGrade() {
		return grade;
	}


	public void setRate(Integer rate) {
		this.rate = rate;
	}


	public Integer getRate() {
		return rate;
	}


	public void setNearSubmitTime(Date nearSubmitTime) {
		this.nearSubmitTime = nearSubmitTime;
	}


	public Date getNearSubmitTime() {
		return nearSubmitTime;
	}
	
	public void setExecutor(Person executor) {
		this.executor = executor;
	}

	public Person getExecutor() {
		return executor;
	}

	public void setJoiner(Set<Person> joiner) {
		this.joiner = joiner;
	}

	public Set<Person> getJoiner() {
		return joiner;
	}

	


	public void setAttachs(Set<TaskAttach> attachs) {
		this.attachs = attachs;
	}

	public Set<TaskAttach> getAttachs() {
		return attachs;
	}

	public void setResults(Set<Attachment> results) {
		this.results = results;
	}


	public Set<Attachment> getResults() {
		return results;
	}


	public void setReferences(Set<Attachment> references) {
		this.references = references;
	}

	public Set<Attachment> getReferences() {
		return references;
	}

	public void setSummary(String summary) {
		this.summary = summary;
	}

	public String getSummary() {
		return summary;
	}

	public void setStartTime(Date startTime) {
		this.startTime = startTime;
	}

	public Date getStartTime() {
		return startTime;
	}

	public void setEndTime(Date endTime) {
		this.endTime = endTime;
	}

	public Date getEndTime() {
		return endTime;
	}

	public void setRealStartTime(Date realStartTime) {
		this.realStartTime = realStartTime;
	}

	public Date getRealStartTime() {
		return realStartTime;
	}

	public void setRealEndTime(Date realEndTime) {
		this.realEndTime = realEndTime;
	}

	public Date getRealEndTime() {
		return realEndTime;
	}

	public void setCycles(Integer cycles) {
		this.cycles = cycles;
	}

	public Integer getCycles() {
		return cycles;
	}

	public void setCycleType(Integer cycleType) {
		this.cycleType = cycleType;
	}

	public Integer getCycleType() {
		return cycleType;
	}

	public void setLastSubmitTime(Date lastSubmitTime) {
		this.lastSubmitTime = lastSubmitTime;
	}

	public Date getLastSubmitTime() {
		return lastSubmitTime;
	}

	public void setStatus(Integer status) {
		this.status = status;
	}

	public Integer getStatus() {
		return status;
	}

	public void setRemark(String remark) {
		this.remark = remark;
	}

	public String getRemark() {
		return remark;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}
	
	public void setCritiques(Set<TaskCritique> critiques) {
		this.critiques = critiques;
	}

	public Set<TaskCritique> getCritiques() {
		return critiques;
	}
	
	public void setPerusals(Set<Person> perusals) {
		this.perusals = perusals;
	}


	public Set<Person> getPerusals() {
		return perusals;
	}
	
	public void addAllPerusals(Collection<Person> persons)
	{
		if (persons!=null)
		{
			if (perusals==null)
				perusals = new HashSet<Person>();
			perusals.addAll(persons);
		}
	}
	
	public void addAllJoiner(Collection<Person> persons)
	{
		if (persons!=null)
		{
			if (joiner==null)
				joiner = new HashSet<Person>();
			joiner.addAll(persons);
		}
	}
	
	public void addReference(Attachment attachment)
	{
		if (references==null)
			references = new HashSet<Attachment>();
		references.add(attachment);
	}
	
	public void addAllReference(Collection<Attachment> attachs)
	{
		if (references==null)
			references = new HashSet<Attachment>();
		references.addAll(attachs);
	}
	
	public void addResult(Attachment attachment)
	{
		if (results==null)
			results = new HashSet<Attachment>();
		results.add(attachment);
	}
	
	public void addAllResults(Collection<Attachment> attachs)
	{
		if (results==null)
			results = new HashSet<Attachment>();
		results.addAll(attachs);
	}
	
	public void addTaskAttach(TaskAttach attach)
	{
		if (attachs==null)
			attachs = new HashSet<TaskAttach>();
		attachs.add(attach);
	}
	
	public void addCritique(TaskCritique critique)
	{
		if (critiques==null)
			critiques = new HashSet<TaskCritique>();
		critiques.add(critique);
	}
	
	
	public void adjustNearSubmiTime() throws Exception
	{
		Date begin = (this.getLastSubmitTime()==null)?this.getStartTime()
															:this.getLastSubmitTime();
		if (begin!=null
				&& this.getCycles()!=null)
		{
			this.setNearSubmitTime(Util.addTimeByDay(begin, this.cycles*this.cycleType));
		}
	}
	
	
	/**
	 * 重载判断是否锁定
	 */
	@Override
	public  boolean getLocked()
	{
		if (this.getStatus()!=null && this.getStatus()==Constrains.TASK_STATUS_FROST)
		{
			return true;
		}
		else
		{
			return super.getLocked();
		}
	}
	
	public boolean getSubmitOverTime()
	{
		if (this.getNearSubmitTime()!=null)
		{
			if (this.getNearSubmitTime().compareTo(Util.nowFullTime())<=0)
				return true;
		}
		return false;
	}
	
	/**
	 * 获取提交计划
	 * @return
	 */
	public int getSubmitPlan()
	{
		int day = this.cycles*this.cycleType;
		int count = 1;
		Calendar aCalendar = Calendar.getInstance();
		aCalendar.setTime(startTime);
		int day1 = aCalendar.get(Calendar.DAY_OF_YEAR);
		aCalendar.setTime(endTime);
		int day2 = aCalendar.get(Calendar.DAY_OF_YEAR);
		count = (day2-day1)/day;
		return (count<1)?1:count;
		
	}



}

	